﻿using SanlieHash.Fast;
using System;
using xlstool;

namespace paiban.data
{
    internal class DasaoTable
    {
        internal string[] daosao_table;
        internal int daosao_table_size;
        internal int day_useperson = 2;
        internal int now_day = 1;
        internal string[] no_dasao_person;
        internal int dasao_person_count;
        internal WorkPersonInfo info { get; set; }
        public DasaoTable(WorkPersonInfo info)
        {
            this.info = info;
            no_dasao_person = cgsys.config.Array("不参与打扫人员");
            daosao_table_size = info.days * day_useperson;
            daosao_table = new string[daosao_table_size];

            dasao_person_count = 0;
            foreach (var person in info.LoopWorkPersons()) if (!no_dasao_person.Contains(person)) dasao_person_count++;
        }
        public void Goto(int day)
        {
            now_day = day;
        }
        public IEnumerable<string> ReadDasaoPerson()
        {
            return ReadDasaoPerson(now_day);
        }
        public IEnumerable<string> ReadDasaoPerson(int day)
        {
            int i = 0;
            foreach (var person in info.ReadWanbanPerson(day)) if (!no_dasao_person.Contains(person))
                {
                    yield return person;
                    i++;
                }

            // 不满住最小人数，拉2个早
            if (i < day_useperson) foreach (var person in info.ReadNotWanbanPerson(day)) if (!no_dasao_person.Contains(person))
                    {
                        yield return person;
                        i++;
                        if (i > day_useperson) break;
                    }
        }
        public IEnumerable<string> LoopDasaoPerson()
        {
            foreach (var person in info.LoopWorkPersons()) if (!no_dasao_person.Contains(person)) yield return person;
        }
        public IEnumerable<int> LoopDaosaoNo()
        {
            for (int i = 0; i < day_useperson; i++) yield return i;
        }
        public IEnumerable<string> Read(int day)
        {
            var max = day * day_useperson;
            for (int i = max - day_useperson; i < max; i++) yield return daosao_table[i];
        }
        public string Read(int day, int no)
        {
            return daosao_table[(day - 1) * day_useperson + no];
        }
        public IEnumerable<string> Read()
        {
            return Read(now_day);
        }
        public bool IsIn(string person)
        {
            foreach (var p in Read())if (person == p) return true;
            return false;
        }
        public void Change(int day, string oldname, string newname)
        {
            var max = day * day_useperson;
            for (int i = max - day_useperson; i < max; i++)
                if (daosao_table[i] == oldname) daosao_table[i] = newname;
        }
        public void Change(string oldname, string newname)
        {
            Change(now_day, oldname, newname);
        }
        public void Entry(IEnumerator<string> persons)
        {
            for (var i = 0; persons.MoveNext() && i < day_useperson; i++) Entry(now_day, i, persons.Current);
        }
        public void Entry(int no, string person)
        {
            Entry(now_day, no, person);
        }
        public void Entry(int day, int no, string person)
        {
            if (no < 0 || no >= day_useperson) throw new ArgumentException();
            daosao_table[(day - 1) * day_useperson + no] = person;
        }
        public string CalcHash()
        {
            return FastGuoMi.GetSM3(string.Join("+", daosao_table));
        }
        public void FillExcelSheet(Excel2003Sheet pb)
        {
            var rowno = 1;
            var cellno = 1;
            var row = pb.ToRow(rowno);
            row.ToCell(cellno++).SetValue("日期");
            foreach (var no in LoopDaosaoNo()) row.ToCell(cellno++).SetValue($"打扫人 {no + 1}");
            foreach (var no in LoopDaosaoNo()) row.ToCell(cellno++).SetValue($"其她班次人员 {no + 1}");

            foreach (var day in info.LoopDays())
            {
                rowno++;
                row = pb.ToRow(rowno);
                cellno = 1;
                row.ToCell(cellno++).SetValue($"{info.month}月{day}日");

                foreach (var no in LoopDaosaoNo()) row.ToCell(cellno++).SetValue(Read(day, no));
                foreach (var no in LoopDaosaoNo()) if (!info.ReadWanbanPerson(day).Contains(Read(day, no))) row.ToCell(cellno++).SetValue($"{Read(day, no)}");
            }
        }
    }
}
